package com.example.fastexcel.listener;

import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.read.listener.ReadListener;
import com.example.fastexcel.model.dto.UserExcelDTO;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * Excel导入数据验证监听器
 * 在读取Excel数据时进行数据验证
 */
@Slf4j
public class UserExcelDataListener implements ReadListener<UserExcelDTO> {
    
    /**
     * 每批处理的数据量
     */
    private static final int BATCH_COUNT = 100;
    
    /**
     * 临时存储数据的列表
     */
    private final List<UserExcelDTO> cachedData = new ArrayList<>();
    
    /**
     * 存储验证错误信息
     */
    private final List<String> errorMessages = new ArrayList<>();
    
    /**
     * 行号计数器（从1开始，包含表头）
     */
    private int currentRow = 1;
    
    @Override
    public void invoke(UserExcelDTO data, AnalysisContext context) {
        currentRow++;
        
        // 验证数据
        String validationError = validateData(data, currentRow);
        if (validationError != null) {
            errorMessages.add("第" + currentRow + "行: " + validationError);
            return; // 跳过无效数据
        }
        
        // 添加到缓存
        cachedData.add(data);
        
        // 达到批次数量时处理数据
        if (cachedData.size() >= BATCH_COUNT) {
            saveData();
            cachedData.clear();
        }
    }
    
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 处理剩余数据
        saveData();
        cachedData.clear();
        
        // 输出验证结果
        if (!errorMessages.isEmpty()) {
            log.warn("Excel导入完成，发现 {} 个验证错误", errorMessages.size());
            errorMessages.forEach(log::warn);
        } else {
            log.info("Excel导入完成，所有数据验证通过");
        }
    }
    
    /**
     * 保存数据到数据库（实际项目中实现）
     */
    private void saveData() {
        if (!cachedData.isEmpty()) {
            log.info("保存 {} 条数据到数据库", cachedData.size());
            // 实际项目中这里应该调用Service层保存数据
            // userService.saveBatch(cachedData);
        }
    }
    
    /**
     * 验证单行数据
     * 
     * @param data 要验证的数据
     * @param rowNumber 行号
     * @return 验证错误信息，null表示验证通过
     */
    private String validateData(UserExcelDTO data, int rowNumber) {
        // 验证用户名
        if (StrUtil.isBlank(data.getUsername())) {
            return "用户名不能为空";
        }
        if (data.getUsername().length() > 50) {
            return "用户名长度不能超过50个字符";
        }
        
        // 验证真实姓名
        if (StrUtil.isBlank(data.getRealName())) {
            return "真实姓名不能为空";
        }
        
        // 验证邮箱格式
        if (StrUtil.isNotBlank(data.getEmail())) {
            if (!data.getEmail().matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")) {
                return "邮箱格式不正确";
            }
        }
        
        // 验证手机号格式
        if (StrUtil.isNotBlank(data.getPhone())) {
            if (!data.getPhone().matches("^1[3-9]\\d{9}$")) {
                return "手机号格式不正确";
            }
        }
        
        // 验证年龄范围
        if (data.getAge() != null) {
            if (data.getAge() < 0 || data.getAge() > 150) {
                return "年龄必须在0-150之间";
            }
        }
        
        // 验证工资
        if (data.getSalary() != null) {
            if (data.getSalary().compareTo(java.math.BigDecimal.ZERO) < 0) {
                return "工资不能为负数";
            }
        }
        
        // 验证状态
        if (data.getStatus() != null) {
            if (data.getStatus() != 0 && data.getStatus() != 1) {
                return "状态只能为0（禁用）或1（启用）";
            }
        }
        
        return null; // 验证通过
    }
    
    /**
     * 获取验证错误信息
     * 
     * @return 错误信息列表
     */
    public List<String> getErrorMessages() {
        return new ArrayList<>(errorMessages);
    }
    
    /**
     * 是否存在验证错误
     * 
     * @return true表示存在错误
     */
    public boolean hasErrors() {
        return !errorMessages.isEmpty();
    }
}
